#include <regx52.h>
#include "IR.h"

/**
 * @brief 系统状态定义
 * 
 * FREE: 空闲状态
 * STARE: 等待状态
 * DATA: 数据解码状态
 * FINISH: 解码完成状态
 */
unsigned char state = FREE; // 当前系统状态

unsigned int Time = 0;      // 定时器当前时间
unsigned int Time_ = 0;     // 定时器捕获时间
unsigned char Data[4] = 0;  // 解码数据存储
unsigned char Bit = 0;      // 当前已解码位数
unsigned char Address = 0;  // 解码得到的地址
unsigned char Command = 0;  // 解码得到的命令
unsigned char Com_flag = 0; // 命令标志位，用于确认解码完成
unsigned char Rep_flag = 0; // 重复信号标志位，用于确认重复信号

/**
 * @brief 获取命令完成标志
 * 
 * @return unsigned char 1 表示命令完成，0 表示未完成
 */
unsigned char Command_Flag()
{
    if (Com_flag == 1)
    {
        Com_flag = 0;

        return 1;
    }
    else
        return 0;
}

/**
 * @brief 获取重复信号标志
 * 
 * @return unsigned char 1 表示重复信号，0 表示没有重复信号
 */
unsigned char Repeat_Flag()
{
    if (Rep_flag == 1)
    {
        Rep_flag = 0;

        return 1;
    }
    else
        return 0;
}

/**
 * @brief 获取解码后的地址
 * 
 * @return unsigned char 地址值；如果解码未完成，返回 0
 */
unsigned char Re_Address()
{
    return Address;
}

/**
 * @brief 获取解码后的命令
 * 
 * @return unsigned char 命令值；如果解码未完成，返回 0
 */
unsigned char Re_Command()
{
    return Command;
}

/**
 * @brief 控制 Timer0 的启停
 * 
 * @param command 1 表示启动定时器，0 表示停止定时器
 */
void Timer0_Timing(unsigned char command)
{
    TR0 = command;
}

/**
 * @brief 初始化定时器的时间值
 * 
 * @param command 定时器初始值（16 位）
 */
void TimeInit(unsigned char command)
{
    TH0 = command / 256; // 高 8 位
    TL0 = command % 256; // 低 8 位
}

/**
 * @brief 获取当前定时器计时值
 * 
 * @return unsigned int 当前计时值（16 位）
 */
unsigned int Timer0_Gettime()
{
    Time = TH0 << 8 | TL0; // 合并高低位
    return Time;
}

/**
 * @brief 外部中断 0 服务函数，用于红外数据捕获和解码
 */
void Int0_Routine() interrupt 0
{
    // 检测到下降沿信号，开始解码
    if (state == FREE)
    {
        TimeInit(0);         // 初始化定时器
        Timer0_Timing(1);    // 启动定时器
        state = STARE;       // 转为等待状态
        return;
    }
    if (state == STARE)
    {
        Timer0_Timing(0);    // 停止定时器
        Time_ = Timer0_Gettime(); // 获取捕获时间
        if ((Time_ <= 12500 + 500) && (Time_ >= 12500 - 500)) // 起始信号
        {
            TimeInit(0);
            Timer0_Timing(1);
            state = DATA;    // 转为数据解码状态
            return;
        }
        else if ((Time_ <= 10500 + 500) && (Time_ >= 10500 - 500)) // 重复信号
        {
            Rep_flag = 1;     // 标志重复信号
            state = FREE;    // 返回空闲状态
            return;
        }
        else
        {
            state = FREE;    // 出错，返回空闲状态
            return;
        }
    }
    // 进入解码阶段
    if (state == DATA)
    {
        Timer0_Timing(0);
        Time_ = Timer0_Gettime();
        if (Bit < 32)
        {
            if ((Time_ >= 1120 - 500) && (Time_ <= 1120 + 500)) // 逻辑 0
            {
                Data[Bit / 8] = Data[Bit / 8] | (0x00 << Bit % 8);
                Bit++;
                TimeInit(0);
                Timer0_Timing(1);
                return;
            }
            else if ((Time_ >= 2250 - 500) && (Time_ <= 2250 + 500)) // 逻辑 1
            {
                Data[Bit / 8] = Data[Bit / 8] | (0x01 << Bit % 8);
                Bit++;
                TimeInit(0);
                Timer0_Timing(1);
                return;
            }
            else
            {
                state = FREE; // 出错，返回空闲状态
                return;
            }
        }
    }
    // 解码结束
    if (Bit == 32)
    {
        Com_flag = 1; // 标志解码完成
        if (Data[0] == ~Data[1] && Data[2] == ~Data[3]) // 校验数据
        {
            Address = Data[0];
            Command = Data[2];
        }
        Bit = 0;              // 清零位计数
        Data[0] = Data[1] = Data[2] = Data[3] = 0; // 清空数据
        state = FINISH;
        Timer0_Timing(0);
        TimeInit(0);
        return;
    }
    if (state == FINISH)
    {
        state = FREE;         // 解码完成后重置状态
    }
    // 注意：完全清除 32 位数据后的下降沿状态
}
